use super::operator;
use crate::config::app_error::AppResult;
use crate::extension::index::index::query::query::query_factory;
use crate::extension::index::router::list_options::ListOptions;
use crate::extension::index::selector::field_selector::FieldSelector;
use crate::extension::index::selector::label_selector::LabelSelector;
use halo_model::ExtensionOperator;

pub fn label_and_field_selector_to_list_options<T: ExtensionOperator + 'static>(
    label_selector_terms: Vec<String>,
    field_selector_terms: Vec<String>,
) -> AppResult<ListOptions> {
    let label_matchers = label_selector_terms
        .iter()
        .map(|it| operator::convert_selector(it.clone()))
        .filter_map(|it| it)
        .map(|it| operator::convert_label(it))
        .collect::<Vec<_>>();

    let field_query = field_selector_terms
        .iter()
        .map(|it| operator::convert_selector(it.clone()))
        .filter_map(|it| it)
        .filter_map(|it| operator::convert_field(it).ok())
        .collect::<Vec<_>>();

    let label_selector = LabelSelector::new(label_matchers);
    let field_selector;
    if field_query.is_empty() {
        field_selector = FieldSelector::all(query_factory::all());
    } else {
        field_selector = FieldSelector::of(query_factory::and_vec(field_query)?);
    }
    let list_options = ListOptions::new(label_selector, field_selector);
    Ok(list_options)
}
